import requests
import math
from datetime import datetime
from .market_state_analyzer import MarketStateAnalyzer

class CryptoAnalyzer:
    def __init__(self):
        self.symbols = ['BTCUSDT']
        self.historical_data = {}
        self.current_signals = {}
        self.backtester = Backtester()
        self.market_state_analyzer = MarketStateAnalyzer()
        
        for symbol in self.symbols:
            self.historical_data[symbol] = {}
            self.current_signals[symbol] = {}
    
    def fetch_historical_data(self, symbol, interval, limit=500):
        try:           
            # [[1754614740000,"117281.40","117299.20","117232.40","117232.40","29.251",1754614799999,"3429748.27580",1220,"15.917","1866239.10370","0"]]
            # 开盘时间：2025-08-08 09:02:34 (北京时间)
            # 开盘价：117281.40 USDT
            # 最高价：117299.20 USDT
            # 最低价：117232.40 USDT
            # 收盘价：117232.40 USDT
            # 成交量：29.251 BTC
            # 收盘时间：2025-08-08 09:03:34 (北京时间)
            # 成交额：3429748.27580 USDT
            # 成交笔数：1220笔
            # 主动买入成交量：15.917 BTC
            # 主动买入成交额：1866239.10370 USDT
            # 忽略值：0

            url = f"https://bnapi.bnlex.top/fapi/fapi/v1/klines?symbol={symbol}&interval={interval}&limit={limit}"
            response = requests.get(url)
            data = response.json()
            
            return [
                {
                    'time': math.floor(item[0] / 1000),
                    'open': float(item[1]),
                    'high': float(item[2]),
                    'low': float(item[3]),
                    'close': float(item[4]),
                    'volume': float(item[5]),
                    'closeTime': item[6]
                }
                for item in data
            ]
        except Exception as e:
            print(f"获取{symbol}历史数据失败: {e}")
            return None
    
    def convert_to_higher_timeframe(self, data, factor):
        converted = []
        for i in range(0, len(data) - factor + 1, factor):
            chunk = data[i:i+factor]
            new_candle = {
                'time': chunk[0]['time'],
                'open': chunk[0]['open'],
                'high': max(c['high'] for c in chunk),
                'low': min(c['low'] for c in chunk),
                'close': chunk[-1]['close'],
                'volume': sum(c['volume'] for c in chunk),
                'closeTime': chunk[-1]['closeTime']
            }
            converted.append(new_candle)
        return converted
    
    async def fetch_data_for_all_symbols(self, interval):
        for symbol in self.symbols:
            fetch_interval = interval
            if interval == '10m':
                fetch_interval = '5m'
            elif interval == '30m':
                fetch_interval = '15m'
            # 对于5分钟周期，直接使用5m
            elif interval == '5m':
                fetch_interval = '5m'

            raw_data = self.fetch_historical_data(symbol, fetch_interval)
            if not raw_data:
                continue

            if interval in ['10m', '30m']:
                data = self.convert_to_higher_timeframe(raw_data, 2)
            else:
                data = raw_data

            self.historical_data[symbol][interval] = data
    
    def calculate_rsi(self, data, period=14):
        if len(data) < period + 1:
            return [None] * len(data)
        
        rsi = [None] * period
        avg_gain = 0.0
        avg_loss = 0.0
        
        for i in range(1, period + 1):
            change = data[i]['close'] - data[i-1]['close']
            if change > 0:
                avg_gain += change
            else:
                avg_loss += abs(change)
        
        avg_gain /= period
        avg_loss /= period
        
        rs = avg_gain / avg_loss if avg_loss != 0 else 100
        rsi.append(100 - (100 / (1 + rs)))
        
        for i in range(period + 1, len(data)):
            change = data[i]['close'] - data[i-1]['close']
            gain = change if change > 0 else 0
            loss = abs(change) if change < 0 else 0
            
            avg_gain = (avg_gain * (period - 1) + gain) / period
            avg_loss = (avg_loss * (period - 1) + loss) / period
            
            rs = avg_gain / avg_loss if avg_loss != 0 else 100
            rsi.append(100 - (100 / (1 + rs)))
        
        return rsi
    
    def calculate_ema(self, data, period):
        ema = [None] * (period - 1)
        if len(data) < period:
            return ema
        
        sum_close = sum(d['close'] for d in data[:period])
        ema.append(sum_close / period)
        
        multiplier = 2 / (period + 1)
        for i in range(period, len(data)):
            current_ema = (data[i]['close'] - ema[i-1]) * multiplier + ema[i-1]
            ema.append(current_ema)
        
        return ema
    
    def calculate_macd(self, data, short_period=12, long_period=26, signal_period=9):
        if len(data) < long_period + signal_period:
            return {
                'dif': [None] * len(data),
                'dea': [None] * len(data),
                'macd': [None] * len(data)
            }
        
        short_ema = self.calculate_ema(data, short_period)
        long_ema = self.calculate_ema(data, long_period)
        
        dif = []
        for s, l in zip(short_ema, long_ema):
            if s is not None and l is not None:
                dif.append(s - l)
            else:
                dif.append(None)
        
        dea_data = [{'close': d if d is not None else 0, 'time': data[i]['time']} 
                   for i, d in enumerate(dif)]
        dea = self.calculate_ema(dea_data, signal_period)
        
        macd = []
        for d, s in zip(dif, dea):
            if d is not None and s is not None:
                macd.append((d - s) * 2)
            else:
                macd.append(None)
        
        return {'dif': dif, 'dea': dea, 'macd': macd}
    
    def calculate_kdj(self, data, period=9, k_period=3, d_period=3):
        if len(data) < period + d_period:
            return {
                'k': [None] * len(data),
                'd': [None] * len(data),
                'j': [None] * len(data)
            }
        
        k_values = []
        d_values = []
        j_values = []
        
        for i in range(len(data)):
            if i < period - 1:
                k_values.append(None)
                d_values.append(None)
                j_values.append(None)
                continue
            
            high = max(data[j]['high'] for j in range(i - period + 1, i + 1))
            low = min(data[j]['low'] for j in range(i - period + 1, i + 1))
            close = data[i]['close']
            
            if high == low:
                rsv = 0
            else:
                rsv = (close - low) / (high - low) * 100
            
            if k_values[i-1] is not None:
                k = (k_values[i-1] * (k_period - 1) + rsv) / k_period
            else:
                k = rsv
            
            if d_values[i-1] is not None:
                d = (d_values[i-1] * (d_period - 1) + k) / d_period
            else:
                d = k
            
            j = 3 * k - 2 * d
            
            k_values.append(k)
            d_values.append(d)
            j_values.append(j)
        
        return {'k': k_values, 'd': d_values, 'j': j_values}
    
    def calculate_ma(self, data, period):
        ma = []
        for i in range(len(data)):
            if i < period - 1:
                ma.append(None)
                continue
            
            sum_close = sum(data[j]['close'] for j in range(i - period + 1, i + 1))
            ma.append(sum_close / period)
        
        return ma
    
    def get_trend(self, values, index):
        if index < 2 or values[index] is None or values[index-1] is None:
            return 'neutral'
        return 'up' if values[index] > values[index-1] else 'down'
    
    def get_macd_trend(self, macd, index):
        if index < 2 or macd['dif'][index] is None or macd['dea'][index] is None:
            return 'neutral'
        
        dif = macd['dif'][index]
        dea = macd['dea'][index]
        prev_dif = macd['dif'][index-1]
        prev_dea = macd['dea'][index-1]
        
        macd_above = dif > dea
        macd_prev_above = prev_dif > prev_dea
        macd_increasing = dif > prev_dif
        dea_increasing = dea > prev_dea
        
        if macd_above:
            if not macd_prev_above:
                return 'crossUp'
            return 'strongUp' if macd_increasing and dea_increasing else 'up'
        else:
            if macd_prev_above:
                return 'crossDown'
            return 'strongDown' if not macd_increasing and not dea_increasing else 'down'
    
    def get_kdj_cross(self, kdj, index):
        if index < 2 or kdj['k'][index] is None or kdj['d'][index] is None:
            return 'neutral'
        
        k = kdj['k'][index]
        d = kdj['d'][index]
        prev_k = kdj['k'][index-1]
        prev_d = kdj['d'][index-1]
        
        if k > d and prev_k < prev_d:
            return 'goldenCross'
        if k < d and prev_k > prev_d:
            return 'deathCross'
        if k > d:
            return 'above'
        if k < d:
            return 'below'
        return 'neutral'
    
    def calculate_fisher(self, data, period=9):
        if len(data) < period:
            return [None] * len(data)
    
        fisher = [None] * len(data)
        mid_prices = [(d['high'] + d['low']) / 2 for d in data]
    
        for i in range(period, len(data)):
            # 归一化价格到-1到1之间
            highest_high = max(mid_prices[i-period:i+1])
            lowest_low = min(mid_prices[i-period:i+1])
            if highest_high == lowest_low:
                norm_price = 0
            else:
                norm_price = 2 * ((mid_prices[i] - lowest_low) / (highest_high - lowest_low)) - 1
            
            # 确保norm_price在有效范围内
            norm_price = max(-0.999, min(0.999, norm_price))
    
            # Fisher转换 - 添加边界检查避免数学错误
            if abs(norm_price) >= 0.999:
                # 当norm_price接近边界时，设为中性值
                fisher[i] = 0.0
            else:
                fisher[i] = 0.5 * math.log((1 + norm_price) / (1 - norm_price))
    
        return fisher
    
    def detect_trend(self, signals, weights=None):
        # 大周期右侧函数 - 优化版本
        
        # 默认权重或使用传入的权重 - 调整权重以提高胜率
        if weights is None:
            weights = {'fisher': 0.4, 'macd': 0.35, 'kdj': 0.25}
        
        fisher_weight = weights['fisher']
        macd_weight = weights['macd']
        kdj_weight = weights['kdj']

        # 计算各指标得分
        fisher_score = 0.0
        macd_score = 0.0
        kdj_score = 0.0
        rsi_confirmation = 0.0  # 新增RSI确认得分

        # Fisher趋势得分 - 增强判断逻辑
        if signals['fisherTrend'] == 'up':
            fisher_score = 1.2  # 增强Fisher上涨信号
        elif signals['fisherTrend'] == 'down':
            fisher_score = -1.2  # 增强Fisher下跌信号

        # MACD趋势得分 - 使用5分钟数据，更细致的分类
        macd_trend_key = 'macdTrend_5min' if 'macdTrend_5min' in signals else 'macdTrend'
        if signals[macd_trend_key] == 'crossUp':
            macd_score = 1.3  # 金叉最强信号
        elif signals[macd_trend_key] == 'strongUp':
            macd_score = 1.0  # 强势上涨
        elif signals[macd_trend_key] == 'up':
            macd_score = 0.6  # 一般上涨
        elif signals[macd_trend_key] == 'crossDown':
            macd_score = -1.3  # 死叉最强信号
        elif signals[macd_trend_key] == 'strongDown':
            macd_score = -1.0  # 强势下跌
        elif signals[macd_trend_key] == 'down':
            macd_score = -0.6  # 一般下跌

        # KDJ交叉得分 - 使用5分钟数据，增强判断逻辑
        kdj_cross_key = 'kdjCross_5min' if 'kdjCross_5min' in signals else 'kdjCross'
        if signals[kdj_cross_key] == 'goldenCross':
            kdj_score = 1.1  # 金叉信号
        elif signals[kdj_cross_key] == 'deathCross':
            kdj_score = -1.1  # 死叉信号
        elif signals[kdj_cross_key] == 'above':  # K在D上方
            kdj_score = 0.4  # 轻微看涨
        elif signals[kdj_cross_key] == 'below':  # K在D下方
            kdj_score = -0.4  # 轻微看跌

        # RSI确认得分 - 基于RSI值进行确认
        rsi_value = signals.get('rsi', 50)
        if rsi_value is not None:
            if rsi_value > 65:  # RSI较高，可能超买
                rsi_confirmation = -0.3  # 轻微看跌确认
            elif rsi_value < 35:  # RSI较低，可能超卖
                rsi_confirmation = 0.3  # 轻微看涨确认
            elif 45 <= rsi_value <= 55:  # RSI中性区域
                rsi_confirmation = 0.1 if (fisher_score + macd_score) > 0 else -0.1  # 跟随主趋势

        # 计算综合得分
        total_score = (fisher_score * fisher_weight + 
                      macd_score * macd_weight + 
                      kdj_score * kdj_weight +
                      rsi_confirmation * 0.1)  # RSI确认权重较小

        # 动态阈值调整 - 根据信号强度调整阈值
        signal_threshold = 0.15  # 降低阈值以提高敏感性
        
        # 根据综合得分确定方向和置信度
        macd_trend_for_return = signals.get('macdTrend_5min', signals.get('macdTrend', 'neutral'))
        if total_score > signal_threshold:
            # 增强置信度计算
            confidence = min(0.88, abs(total_score) * 0.7 + 0.25)
            return {
                'direction': 'up',
                'confidence': confidence,
                'type': 'trend',
                'rsi': signals['rsi'],
                'macdTrend': macd_trend_for_return
            }
        elif total_score < -signal_threshold:
            # 增强置信度计算
            confidence = min(0.88, abs(total_score) * 0.7 + 0.25)
            return {
                'direction': 'down',
                'confidence': confidence,
                'type': 'trend',
                'rsi': signals['rsi'],
                'macdTrend': macd_trend_for_return
            }

        # 返回中性信号 - 优化中性置信度
        neutral_confidence = max(0.4, 1.0 - abs(total_score) * 1.5)
        return {
            'direction': 'neutral',
            'confidence': neutral_confidence,
            'type': 'trend',
            'rsi': signals['rsi'],
            'macdTrend': macd_trend_for_return
        }
    
    def detect_reversal(self, signals, data=None, weights=None):
        # 小周期右侧函数 (1分钟周期) - 增强版，支持震荡和单边行情的动态调整
        
        # 价格位置判断 - 防止追涨杀跌
        price_position_score = self.evaluate_price_position(data) if data else 0
        
        # 判断市场状态（震荡 vs 单边）
        market_state = 'ranging'  # 默认为震荡市场
        trend_strength = 0
        
        if data and len(data) >= 20:
            recent_data = data[-20:]
            prices = [d['close'] for d in recent_data]
            ma5 = sum(prices[-5:]) / 5
            ma10 = sum(prices[-10:]) / 10
            ma20 = sum(prices[-20:]) / 20
            
            # 计算趋势强度
            if ma5 > ma10 > ma20:
                trend_strength = 1  # 强上涨趋势
                market_state = 'strong_trend'
            elif ma5 > ma10 and ma10 > ma20 * 0.998:
                trend_strength = 0.7  # 中等上涨趋势
                market_state = 'moderate_trend'
            elif ma5 < ma10 < ma20:
                trend_strength = -1  # 强下跌趋势
                market_state = 'strong_trend'
            elif ma5 < ma10 and ma10 < ma20 * 1.002:
                trend_strength = -0.7  # 中等下跌趋势
                market_state = 'moderate_trend'
            else:
                market_state = 'ranging'  # 震荡市场
        
        # 根据市场状态动态调整信号阈值
        if market_state == 'ranging':
            # 震荡市场：更严格的位置判断
            if abs(price_position_score) > 0.7:  # 位置极值，强烈不建议交易
                return {
                    'direction': 'neutral',
                    'confidence': 0.85,
                    'type': 'reversal',
                    'macdTrend': signals['macdTrend'],
                    'rsi': signals['rsi'],
                    'reason': 'price_position_extreme_ranging'
                }
            elif abs(price_position_score) > 0.4:  # 位置不佳，降低信号强度
                signal_threshold = 0.35  # 提高阈值
            else:
                signal_threshold = 0.25  # 正常阈值
                
        elif market_state == 'moderate_trend':
            # 中等趋势：适中的位置判断
            if abs(price_position_score) > 0.8:  # 位置极值，强烈不建议交易
                return {
                    'direction': 'neutral',
                    'confidence': 0.85,
                    'type': 'reversal',
                    'macdTrend': signals['macdTrend'],
                    'rsi': signals['rsi'],
                    'reason': 'price_position_extreme_moderate_trend'
                }
            elif abs(price_position_score) > 0.6:  # 位置不佳，降低信号强度
                signal_threshold = 0.3  # 适度提高阈值
            else:
                signal_threshold = 0.2  # 正常阈值
                
        else:  # strong_trend
            # 强趋势：宽松的位置判断，允许趋势延续
            if abs(price_position_score) > 0.9:  # 只有极端位置才阻止交易
                return {
                    'direction': 'neutral',
                    'confidence': 0.85,
                    'type': 'reversal',
                    'macdTrend': signals['macdTrend'],
                    'rsi': signals['rsi'],
                    'reason': 'price_position_extreme_strong_trend'
                }
            elif abs(price_position_score) > 0.7:  # 位置不佳，轻微降低信号强度
                signal_threshold = 0.25  # 轻微提高阈值
            else:
                signal_threshold = 0.15  # 降低阈值，更容易产生信号
        
        # 默认权重或使用传入的权重 - 调整权重以提高胜率
        if weights is None:
            weights = {'macd': 0.5, 'rsi': 0.3, 'volume': 0.2}
        
        macd_weight = weights['macd']
        rsi_weight = weights['rsi']
        volume_weight = weights['volume']

        # 计算各指标得分
        macd_score = 0.0
        rsi_score = 0.0
        volume_score = 0.0
        momentum_score = 0.0  # 新增动量得分

        # MACD趋势得分 - 主要信号来源，增强信号强度
        if signals['macdTrend'] == 'crossDown':
            macd_score = 1.2  # 死叉，强烈下跌信号
        elif signals['macdTrend'] == 'crossUp':
            macd_score = -1.2  # 金叉，强烈上涨信号
        elif signals['macdTrend'] == 'strongUp':
            macd_score = -0.8  # 强烈上涨，继续看涨
        elif signals['macdTrend'] == 'strongDown':
            macd_score = 0.8  # 强烈下跌，继续看跌
        elif signals['macdTrend'] == 'up':
            macd_score = -0.3  # 一般上涨，轻微看涨
        elif signals['macdTrend'] == 'down':
            macd_score = 0.3  # 一般下跌，轻微看跌

        # RSI得分 - 基于超买超卖和趋势双重判断
        rsi_value = signals['rsi']
        if rsi_value is not None:
            if rsi_value > 70:  # 超买区域
                if signals['rsiTrend'] == 'down':  # RSI从超买区域下降
                    rsi_score = 0.8  # 强烈下跌信号
                else:
                    rsi_score = 0.4  # 中等下跌信号
            elif rsi_value < 30:  # 超卖区域
                if signals['rsiTrend'] == 'up':  # RSI从超卖区域上升
                    rsi_score = -0.8  # 强烈上涨信号
                else:
                    rsi_score = -0.4  # 中等上涨信号
            else:
                # 正常区域，基于趋势判断
                if signals['rsiTrend'] == 'up':
                    rsi_score = -0.3  # RSI上升趋势，支持上涨
                elif signals['rsiTrend'] == 'down':
                    rsi_score = 0.3  # RSI下降趋势，支持下跌

        # 成交量得分 - 增强成交量确认逻辑
        volume_ma20 = signals['volume']['ma20']
        current_volume = signals['volume']['current']
        if volume_ma20 is not None and volume_ma20 > 0 and current_volume is not None:
            volume_ratio = current_volume / volume_ma20
            
            if signals['volume']['trend'] == 'up':
                if volume_ratio > 1.5:  # 成交量放大超过50%
                    volume_score = -0.6  # 强烈上涨确认
                elif volume_ratio > 1.2:  # 成交量放大超过20%
                    volume_score = -0.4  # 中等上涨确认
                elif volume_ratio > 1.0:  # 成交量轻微放大
                    volume_score = -0.2  # 轻微上涨确认
            elif signals['volume']['trend'] == 'down':
                if volume_ratio > 1.3:  # 成交量放大但趋势下降，可能抛压
                    volume_score = 0.5  # 中等下跌信号
                elif volume_ratio < 0.8:  # 成交量萎缩
                    volume_score = 0.3  # 轻微下跌信号

        # 动量得分 - 基于MACD柱状图变化
        macd_diff = signals.get('macdDiff', 0)
        if macd_diff is not None:
            if macd_diff > 0 and signals['macdTrend'] in ['strongUp', 'crossUp']:
                momentum_score = -0.4  # 正动量且上涨趋势
            elif macd_diff < 0 and signals['macdTrend'] in ['strongDown', 'crossDown']:
                momentum_score = 0.4  # 负动量且下跌趋势

        # 计算综合得分
        total_score = (macd_score * macd_weight + 
                      rsi_score * rsi_weight + 
                      volume_score * volume_weight +
                      momentum_score * 0.1)  # 动量权重较小
        
        # 价格位置调整 - 根据价格位置调整最终得分
        if price_position_score > 0:  # 价格位置偏高，不利于做多
            total_score = total_score * (1 - abs(price_position_score) * 0.3) + abs(price_position_score) * 0.2
        elif price_position_score < 0:  # 价格位置偏低，不利于做空
            total_score = total_score * (1 - abs(price_position_score) * 0.3) - abs(price_position_score) * 0.2
        
        # 判断反转信号
        if total_score > signal_threshold:
            confidence = min(0.85, abs(total_score) * 0.8 + 0.2)  # 提高置信度计算
            return {
                'direction': 'down',
                'confidence': confidence,
                'type': 'reversal',
                'macdTrend': signals['macdTrend'],
                'rsi': signals['rsi'],
                'price_position': price_position_score,
                'market_state': market_state,
                'trend_strength': trend_strength,
                'signal_threshold': signal_threshold
            }
        elif total_score < -signal_threshold:
            confidence = min(0.85, abs(total_score) * 0.8 + 0.2)  # 提高置信度计算
            return {
                'direction': 'up',
                'confidence': confidence,
                'type': 'reversal',
                'macdTrend': signals['macdTrend'],
                'rsi': signals['rsi'],
                'price_position': price_position_score,
                'market_state': market_state,
                'trend_strength': trend_strength,
                'signal_threshold': signal_threshold
            }

        # 返回中性信号 - 降低中性置信度
        neutral_confidence = max(0.3, 1.0 - abs(total_score) * 1.2)
        return {
            'direction': 'neutral',
            'confidence': neutral_confidence,
            'type': 'reversal',
            'macdTrend': signals['macdTrend'],
            'rsi': signals['rsi'],
            'price_position': price_position_score,
            'market_state': market_state,
            'trend_strength': trend_strength,
            'signal_threshold': signal_threshold
        }
    
    def calculate_td_sequential(self, data, lookback=20):
        """计算TD序列指标，用于识别趋势 exhaustion 和反转信号
        返回: {'buy_setup': int, 'sell_setup': int, 'buy_countdown': int, 'sell_countdown': int}
        """
        if not data or len(data) < lookback:
            return {'buy_setup': 0, 'sell_setup': 0, 'buy_countdown': 0, 'sell_countdown': 0}
        
        prices = [d['close'] for d in data[-lookback:]]
        
        # TD Buy Setup: 连续9个收盘价低于对应4个周期前的收盘价
        buy_setup = 0
        # TD Sell Setup: 连续9个收盘价高于对应4个周期前的收盘价
        sell_setup = 0
        
        for i in range(4, len(prices)):
            # Buy Setup条件
            if prices[i] < prices[i-4]:
                if buy_setup == 0 or (i > 4 and prices[i-1] < prices[i-5]):
                    buy_setup += 1
                else:
                    buy_setup = 1
            else:
                if buy_setup < 9:
                    buy_setup = 0
            
            # Sell Setup条件
            if prices[i] > prices[i-4]:
                if sell_setup == 0 or (i > 4 and prices[i-1] > prices[i-5]):
                    sell_setup += 1
                else:
                    sell_setup = 1
            else:
                if sell_setup < 9:
                    sell_setup = 0
        
        # 简化的TD Countdown（这里只做基本实现）
        buy_countdown = 13 if buy_setup >= 9 else 0
        sell_countdown = 13 if sell_setup >= 9 else 0
        
        return {
            'buy_setup': min(buy_setup, 9),
            'sell_setup': min(sell_setup, 9),
            'buy_countdown': buy_countdown,
            'sell_countdown': sell_countdown
        }
    
    def evaluate_price_position(self, data):
        """评估价格位置，判断是否处于追涨杀跌的不利位置
        返回值范围：[-1, 1]
        正值表示价格位置偏高（不适合做多），负值表示价格位置偏低（不适合做空）
        增强版：加入TD序列判断，优化震荡和单边行情的位置识别
        """
        if not data or len(data) < 20:
            return 0  # 数据不足，返回中性位置
        
        # 获取最近20个数据点的价格信息
        recent_data = data[-20:]
        prices = [d['close'] for d in recent_data]
        
        # 计算TD序列指标
        td_seq = self.calculate_td_sequential(recent_data)
        
        # 1. 计算价格连续变化次数
        consecutive_ups = 0
        consecutive_downs = 0
        max_consecutive_ups = 0
        max_consecutive_downs = 0
        
        for i in range(1, len(prices)):
            if prices[i] > prices[i-1]:
                consecutive_ups += 1
                consecutive_downs = 0
                max_consecutive_ups = max(max_consecutive_ups, consecutive_ups)
            elif prices[i] < prices[i-1]:
                consecutive_downs += 1
                consecutive_ups = 0
                max_consecutive_downs = max(max_consecutive_downs, consecutive_downs)
            else:
                consecutive_ups = 0
                consecutive_downs = 0
        
        # 2. 计算价格变化趋势强度
        price_changes = []
        for i in range(1, len(prices)):
            change = (prices[i] - prices[i-1]) / prices[i-1]
            price_changes.append(change)
        
        # 计算正向和负向变化的累积
        positive_changes = [c for c in price_changes if c > 0]
        negative_changes = [c for c in price_changes if c < 0]
        
        positive_sum = sum(positive_changes)
        negative_sum = abs(sum(negative_changes))
        
        # 3. 计算最近价格相对于近期区间的位置
        recent_high = max(prices[-10:])  # 最近10个周期的最高价
        recent_low = min(prices[-10:])   # 最近10个周期的最低价
        current_price = prices[-1]
        
        if recent_high != recent_low:
            position_in_range = (current_price - recent_low) / (recent_high - recent_low)
        else:
            position_in_range = 0.5
        
        # 4. 计算价格动量是否过度延伸
        # 使用简单移动平均线作为参考
        ma5 = sum(prices[-5:]) / 5
        ma10 = sum(prices[-10:]) / 10
        ma20 = sum(prices[-20:]) / 20
        
        # 价格偏离移动平均线的程度
        deviation_from_ma5 = (current_price - ma5) / ma5
        deviation_from_ma10 = (current_price - ma10) / ma10
        deviation_from_ma20 = (current_price - ma20) / ma20
        
        # 5. 判断市场状态（震荡 vs 单边）
        # 计算价格波动率
        volatility = (recent_high - recent_low) / recent_low if recent_low > 0 else 0
        
        # 计算趋势强度（基于MA排列）
        trend_strength = 0
        if ma5 > ma10 > ma20:
            trend_strength = 1  # 强上涨趋势
        elif ma5 > ma10 and ma10 > ma20 * 0.998:  # 允许小幅误差
            trend_strength = 0.7  # 中等上涨趋势
        elif ma5 < ma10 < ma20:
            trend_strength = -1  # 强下跌趋势
        elif ma5 < ma10 and ma10 < ma20 * 1.002:  # 允许小幅误差
            trend_strength = -0.7  # 中等下跌趋势
        else:
            trend_strength = 0  # 震荡市场
        
        # 6. 综合评分计算
        position_score = 0
        
        # TD序列评分 - 识别趋势exhaustion
        if td_seq['sell_setup'] >= 8:  # 卖出setup接近完成，可能见顶
            position_score += 0.5
        elif td_seq['sell_setup'] >= 6:  # 卖出setup进行中
            position_score += 0.3
            
        if td_seq['buy_setup'] >= 8:  # 买入setup接近完成，可能见底
            position_score -= 0.5
        elif td_seq['buy_setup'] >= 6:  # 买入setup进行中
            position_score -= 0.3
        
        # 根据市场状态调整评分权重
        if abs(trend_strength) < 0.3:  # 震荡市场 - 更严格的位置判断
            # 连续变化次数评分（震荡市场中权重更高）
            if max_consecutive_ups >= 5:  # 连续上涨5次以上
                position_score += 0.5
            elif max_consecutive_ups >= 3:  # 连续上涨3-4次
                position_score += 0.3
                
            if max_consecutive_downs >= 5:  # 连续下跌5次以上
                position_score -= 0.5
            elif max_consecutive_downs >= 3:  # 连续下跌3-4次
                position_score -= 0.3
            
            # 价格变化趋势强度评分（震荡市场中权重更高）
            if positive_sum > 0.03:  # 累积上涨超过3%
                position_score += 0.4
            elif positive_sum > 0.015:  # 累积上涨1.5-3%
                position_score += 0.2
                
            if negative_sum > 0.03:  # 累积下跌超过3%
                position_score -= 0.4
            elif negative_sum > 0.015:  # 累积下跌1.5-3%
                position_score -= 0.2
            
            # 区间位置评分（震荡市场中权重更高）
            if position_in_range > 0.75:  # 价格在区间高位
                position_score += 0.4
            elif position_in_range > 0.6:  # 价格在区间偏高位
                position_score += 0.2
            elif position_in_range < 0.25:  # 价格在区间低位
                position_score -= 0.4
            elif position_in_range < 0.4:  # 价格在区间偏低位
                position_score -= 0.2
                
        else:  # 单边市场 - 更宽松的位置判断，允许趋势延续
            # 连续变化次数评分（单边市场中权重降低）
            if max_consecutive_ups >= 8:  # 连续上涨8次以上才认为过度
                position_score += 0.3
            elif max_consecutive_ups >= 6:  # 连续上涨6-7次
                position_score += 0.15
                
            if max_consecutive_downs >= 8:  # 连续下跌8次以上才认为过度
                position_score -= 0.3
            elif max_consecutive_downs >= 6:  # 连续下跌6-7次
                position_score -= 0.15
            
            # 价格变化趋势强度评分（单边市场中权重降低）
            if positive_sum > 0.08:  # 累积上涨超过8%才认为过度
                position_score += 0.25
            elif positive_sum > 0.05:  # 累积上涨5-8%
                position_score += 0.15
                
            if negative_sum > 0.08:  # 累积下跌超过8%才认为过度
                position_score -= 0.25
            elif negative_sum > 0.05:  # 累积下跌5-8%
                position_score -= 0.15
            
            # 区间位置评分（单边市场中权重降低）
            if position_in_range > 0.85:  # 价格在极端高位
                position_score += 0.3
            elif position_in_range > 0.7:  # 价格在高位
                position_score += 0.15
            elif position_in_range < 0.15:  # 价格在极端低位
                position_score -= 0.3
            elif position_in_range < 0.3:  # 价格在低位
                position_score -= 0.15
        
        # 移动平均线偏离评分（根据趋势强度调整）
        if abs(trend_strength) < 0.3:  # 震荡市场
            if deviation_from_ma5 > 0.015:  # 价格高于MA5超过1.5%
                position_score += 0.25
            elif deviation_from_ma5 < -0.015:  # 价格低于MA5超过1.5%
                position_score -= 0.25
                
            if deviation_from_ma10 > 0.025:  # 价格高于MA10超过2.5%
                position_score += 0.2
            elif deviation_from_ma10 < -0.025:  # 价格低于MA10超过2.5%
                position_score -= 0.2
        else:  # 单边市场
            if deviation_from_ma5 > 0.03:  # 价格高于MA5超过3%
                position_score += 0.15
            elif deviation_from_ma5 < -0.03:  # 价格低于MA5超过3%
                position_score -= 0.15
                
            if deviation_from_ma20 > 0.05:  # 价格高于MA20超过5%
                position_score += 0.1
            elif deviation_from_ma20 < -0.05:  # 价格低于MA20超过5%
                position_score -= 0.1
        
        # 趋势强度调整 - 在强趋势中降低位置判断的严格程度
        if abs(trend_strength) > 0.7:  # 强趋势
            position_score *= 0.6  # 降低位置评分的影响
        elif abs(trend_strength) > 0.4:  # 中等趋势
            position_score *= 0.8  # 适度降低位置评分的影响
        
        # 限制评分范围在[-1, 1]之间
        position_score = max(-1, min(1, position_score))
        
        return position_score
    
    def combine_signals(self, trend, reversal, signals):
        # print("combine_signals-----------------------------------------")
        
        # 处理空信号情况
        if not trend or not reversal:
            return {
                'direction': 'neutral',
                'confidence': 0.5,
                'type': 'combined',
                'rsi': signals.get('rsi', 50),
                'macdTrend': signals.get('macdTrend', 'neutral')
            }
        
        # 获取信号强度和方向
        trend_strength = trend['confidence'] if trend['direction'] != 'neutral' else 0
        reversal_strength = reversal['confidence'] if reversal['direction'] != 'neutral' else 0
        
        # 情况1: 两个信号同向 - 强信号
        if (trend['direction'] == reversal['direction'] and trend['direction'] != 'neutral'):
            # 增强置信度，使用加权平均
            combined_confidence = min(0.92, (trend_strength * 0.6 + reversal_strength * 0.4) + 0.15)
            return {
                'direction': trend['direction'],
                'confidence': combined_confidence,
                'type': 'combined_strong',
                'rsi': signals['rsi'],
                'macdTrend': signals['macdTrend']
            }
        
        # 情况2: 一个信号强，另一个中性 - 中等信号
        elif (trend['direction'] != 'neutral' and reversal['direction'] == 'neutral'):
            if trend_strength > 0.6:  # 趋势信号较强
                return {
                    'direction': trend['direction'],
                    'confidence': min(0.75, trend_strength * 0.8),
                    'type': 'combined_trend_dominant',
                    'rsi': signals['rsi'],
                    'macdTrend': signals['macdTrend']
                }
        
        elif (reversal['direction'] != 'neutral' and trend['direction'] == 'neutral'):
            if reversal_strength > 0.6:  # 反转信号较强
                return {
                    'direction': reversal['direction'],
                    'confidence': min(0.75, reversal_strength * 0.8),
                    'type': 'combined_reversal_dominant',
                    'rsi': signals['rsi'],
                    'macdTrend': signals['macdTrend']
                }
        
        # 情况3: 信号冲突但一方明显更强 - 弱信号
        elif (trend['direction'] != reversal['direction'] and 
              trend['direction'] != 'neutral' and reversal['direction'] != 'neutral'):
            
            strength_diff = abs(trend_strength - reversal_strength)
            
            # 如果强度差异较大，跟随强者
            if strength_diff > 0.3:
                if trend_strength > reversal_strength:
                    return {
                        'direction': trend['direction'],
                        'confidence': min(0.65, trend_strength * 0.6),
                        'type': 'combined_trend_override',
                        'rsi': signals['rsi'],
                        'macdTrend': signals['macdTrend']
                    }
                else:
                    return {
                        'direction': reversal['direction'],
                        'confidence': min(0.65, reversal_strength * 0.6),
                        'type': 'combined_reversal_override',
                        'rsi': signals['rsi'],
                        'macdTrend': signals['macdTrend']
                    }
            
            # 如果强度接近但都不强，返回中性
            elif max(trend_strength, reversal_strength) < 0.5:
                return {
                    'direction': 'neutral',
                    'confidence': 0.6,
                    'type': 'combined_weak_conflict',
                    'rsi': signals['rsi'],
                    'macdTrend': signals['macdTrend']
                }
        
        # 情况4: 两个信号都是中性
        elif (trend['direction'] == 'neutral' and reversal['direction'] == 'neutral'):
            # 如果两个中性信号的置信度都很高，说明市场确实没有明确方向
            if trend['confidence'] > 0.7 and reversal['confidence'] > 0.7:
                return {
                    'direction': 'neutral',
                    'confidence': 0.8,
                    'type': 'combined_strong_neutral',
                    'rsi': signals['rsi'],
                    'macdTrend': signals['macdTrend']
                }
            else:
                return {
                    'direction': 'neutral',
                    'confidence': 0.5,
                    'type': 'combined_weak_neutral',
                    'rsi': signals['rsi'],
                    'macdTrend': signals['macdTrend']
                }
        
        # 默认返回中性信号
        return {
            'direction': 'neutral',
            'confidence': 0.5,
            'type': 'combined_default',
            'rsi': signals['rsi'],
            'macdTrend': signals['macdTrend']
        }

        

    
    def volume_confirms(self, signal, signals):
        volume_trend_match = (signal['direction'] == 'up' and signals['volume']['trend'] == 'up') or \
                            (signal['direction'] == 'down' and signals['volume']['trend'] == 'down')
        return volume_trend_match and signals['volume']['current'] > signals['volume']['ma20']
    
    def generate_prediction(self, signals, data=None, trend_weights=None, reversal_weights=None):
        trend_signal = self.detect_trend(signals, trend_weights)
        trend_signal2 = self.detect_reversal(signals, data, reversal_weights)
        #  大周期和小周期函数结合
        # 打印预测结果--
        # print(trend_signal,trend_signal2)
        # print("-----------------------------------------")

        return self.combine_signals(trend_signal, trend_signal2, signals)
    
    # 缓存5分钟数据，避免频繁更新
    _5min_data_cache = {}  # 使用类变量存储缓存
    _last_cache_time = 0  # 上次更新缓存的分钟数
    
    def get_5min_data(self, symbol):
        current_time = datetime.now().minute
        # 检查是否需要更新缓存 (每5分钟更新一次)
        if current_time % 5 == 0 and current_time != self._last_cache_time:
            # 直接获取5分钟数据
            data = self.fetch_historical_data(symbol, '5m')
            if data:
                # 存储到historical_data中
                if symbol not in self.historical_data:
                    self.historical_data[symbol] = {}
                self.historical_data[symbol]['5m'] = data
                # 更新缓存
                self._5min_data_cache[symbol] = data
                self._last_cache_time = current_time
        # 返回缓存数据
        return self._5min_data_cache.get(symbol, [])

    def calculate_signals(self, data):
        last_index = len(data) - 1
        if last_index < 0:
            return None

        # 获取5分钟周期数据
        symbol = 'BTCUSDT'  # 假设我们只处理BTCUSDT
        five_min_data = self.get_5min_data(symbol)

        ma5 = self.calculate_ma(data, 5)
        ma10 = self.calculate_ma(data, 10)
        ma20 = self.calculate_ma(data, 20)
        rsi = self.calculate_rsi(data, 14)
        macd = self.calculate_macd(data)
        kdj = self.calculate_kdj(data)

        # 计算5分钟周期的MACD和KDJ，用于大周期函数
        macd_5min = None
        kdj_5min = None
        macd_trend_5min = 'neutral'
        kdj_cross_5min = 'neutral'
        
        if len(five_min_data) >= 26:  # MACD需要至少26个数据点
            macd_5min = self.calculate_macd(five_min_data)
            macd_last_index = len(macd_5min['dif']) - 1
            if macd_last_index >= 0:
                macd_trend_5min = self.get_macd_trend(macd_5min, macd_last_index)
        
        if len(five_min_data) >= 9:  # KDJ需要至少9个数据点
            kdj_5min = self.calculate_kdj(five_min_data)
            kdj_last_index = len(kdj_5min['k']) - 1
            if kdj_last_index >= 0:
                kdj_cross_5min = self.get_kdj_cross(kdj_5min, kdj_last_index)

        # 计算Fisher转换 (仅当有足够的5分钟数据时)
        fisher_trend = 'neutral'
        if len(five_min_data) >= 9:
            fisher = self.calculate_fisher(five_min_data)
            fisher_last_index = len(fisher) - 1
            if fisher_last_index >= 0 and fisher[fisher_last_index] is not None:
                # 判断Fisher趋势 (根据数值递增或递减)
                if fisher_last_index > 0 and fisher[fisher_last_index-1] is not None:
                    if fisher[fisher_last_index] > fisher[fisher_last_index-1]:
                        fisher_trend = 'up'
                    elif fisher[fisher_last_index] < fisher[fisher_last_index-1]:
                        fisher_trend = 'down'

        ma5_trend = self.get_trend(ma5, last_index)
        ma10_trend = self.get_trend(ma10, last_index)
        ma20_trend = self.get_trend(ma20, last_index)
        rsi_trend = self.get_trend(rsi, last_index)
        macd_trend = self.get_macd_trend(macd, last_index)
        kdj_cross = self.get_kdj_cross(kdj, last_index)

        volumes = [d['volume'] for d in data]
        volume_ma20_data = [{'close': d['volume']} for d in data]
        volume_ma20 = self.calculate_ma(volume_ma20_data, 20)[last_index]
        volume_trend = self.get_trend(volumes, last_index)

        signals_data = {
            'ma5Trend': ma5_trend,
            'ma10Trend': ma10_trend,
            'ma20Trend': ma20_trend,
            'rsi': rsi[last_index],
            'rsiTrend': rsi_trend,
            'macdDiff': macd['dif'][last_index] - macd['dea'][last_index] if macd['dif'][last_index] and macd['dea'][last_index] else 0,
            'macdTrend': macd_trend,  # 主周期MACD趋势，用于小周期函数
            'kdjCross': kdj_cross,    # 主周期KDJ交叉，用于小周期函数
            'macdTrend_5min': macd_trend_5min,  # 5分钟MACD趋势，用于大周期函数
            'kdjCross_5min': kdj_cross_5min,    # 5分钟KDJ交叉，用于大周期函数
            'fisherTrend': fisher_trend,
            'volume': {
                'current': volumes[last_index],
                'ma20': volume_ma20,
                'trend': volume_trend
            }
        }
        
        prediction = self.generate_prediction(signals_data, data)
        
        return {
            'indicators': {
                'ma5': ma5[last_index],
                'ma10': ma10[last_index],
                'ma20': ma20[last_index],
                'rsi': rsi[last_index],
                'macd': macd,
                'kdj': kdj
            },
            'prediction': prediction
        }
    
    def calculate_signals_with_weights(self, data, trend_weights=None, reversal_weights=None):
        """使用指定权重计算信号"""
        last_index = len(data) - 1
        if last_index < 0:
            return None

        # 获取5分钟周期数据
        symbol = 'BTCUSDT'  # 假设我们只处理BTCUSDT
        five_min_data = self.get_5min_data(symbol)

        ma5 = self.calculate_ma(data, 5)
        ma10 = self.calculate_ma(data, 10)
        ma20 = self.calculate_ma(data, 20)
        rsi = self.calculate_rsi(data, 14)
        macd = self.calculate_macd(data)
        kdj = self.calculate_kdj(data)

        # 计算5分钟周期的MACD和KDJ，用于大周期函数
        macd_5min = None
        kdj_5min = None
        macd_trend_5min = 'neutral'
        kdj_cross_5min = 'neutral'
        
        if len(five_min_data) >= 26:  # MACD需要至少26个数据点
            macd_5min = self.calculate_macd(five_min_data)
            macd_last_index = len(macd_5min['dif']) - 1
            if macd_last_index >= 0:
                macd_trend_5min = self.get_macd_trend(macd_5min, macd_last_index)
        
        if len(five_min_data) >= 9:  # KDJ需要至少9个数据点
            kdj_5min = self.calculate_kdj(five_min_data)
            kdj_last_index = len(kdj_5min['k']) - 1
            if kdj_last_index >= 0:
                kdj_cross_5min = self.get_kdj_cross(kdj_5min, kdj_last_index)

        # 计算Fisher转换 (仅当有足够的5分钟数据时)
        fisher_trend = 'neutral'
        if len(five_min_data) >= 9:
            fisher = self.calculate_fisher(five_min_data)
            fisher_last_index = len(fisher) - 1
            if fisher_last_index >= 0 and fisher[fisher_last_index] is not None:
                # 判断Fisher趋势 (根据数值递增或递减)
                if fisher_last_index > 0 and fisher[fisher_last_index-1] is not None:
                    if fisher[fisher_last_index] > fisher[fisher_last_index-1]:
                        fisher_trend = 'up'
                    elif fisher[fisher_last_index] < fisher[fisher_last_index-1]:
                        fisher_trend = 'down'

        ma5_trend = self.get_trend(ma5, last_index)
        ma10_trend = self.get_trend(ma10, last_index)
        ma20_trend = self.get_trend(ma20, last_index)
        rsi_trend = self.get_trend(rsi, last_index)
        macd_trend = self.get_macd_trend(macd, last_index)
        kdj_cross = self.get_kdj_cross(kdj, last_index)

        volumes = [d['volume'] for d in data]
        volume_ma20_data = [{'close': d['volume']} for d in data]
        volume_ma20 = self.calculate_ma(volume_ma20_data, 20)[last_index]
        volume_trend = self.get_trend(volumes, last_index)

        signals_data = {
            'ma5Trend': ma5_trend,
            'ma10Trend': ma10_trend,
            'ma20Trend': ma20_trend,
            'rsi': rsi[last_index],
            'rsiTrend': rsi_trend,
            'macdDiff': macd['dif'][last_index] - macd['dea'][last_index] if macd['dif'][last_index] and macd['dea'][last_index] else 0,
            'macdTrend': macd_trend,  # 主周期MACD趋势，用于小周期函数
            'kdjCross': kdj_cross,    # 主周期KDJ交叉，用于小周期函数
            'macdTrend_5min': macd_trend_5min,  # 5分钟MACD趋势，用于大周期函数
            'kdjCross_5min': kdj_cross_5min,    # 5分钟KDJ交叉，用于大周期函数
            'fisherTrend': fisher_trend,
            'volume': {
                'current': volumes[last_index],
                'ma20': volume_ma20,
                'trend': volume_trend
            }
        }
        
        # 使用指定权重生成预测
        prediction = self.generate_prediction(signals_data, data, trend_weights, reversal_weights)
        
        return {
            'indicators': {
                'ma5': ma5[last_index],
                'ma10': ma10[last_index],
                'ma20': ma20[last_index],
                'rsi': rsi[last_index],
                'macd': macd,
                'kdj': kdj
            },
            'prediction': prediction
        }
    
    def get_rsi_level_description(self, rsi_value):
        if rsi_value is None:
            return 'N/A'
        if rsi_value > 80:
            return '极端超买'
        if rsi_value > 70:
            return '超买'
        if rsi_value < 20:
            return '极端超卖'
        if rsi_value < 30:
            return '超卖'
        return '中性'
    
    def get_macd_description(self, macd_trend):
        descriptions = {
            'strongUp': 'MACD指标呈强劲上升趋势',
            'crossUp': 'MACD指标形成金叉',
            'strongDown': 'MACD指标呈强劲下降趋势',
            'crossDown': 'MACD指标形成死叉',
            'neutral': 'MACD指标呈中性'
        }
        return descriptions.get(macd_trend, 'MACD指标无明显趋势')
    
    def get_operation_suggestion(self, prediction):
        # 简化操作建议逻辑
        # high_confidence = prediction['confidence'] >= 0.65
        
        if prediction['direction'] == 'up':
            return '买入' 
        elif prediction['direction'] == 'down':
            return '卖出' 
        # else:
        #     return '买入' if prediction['confidence'] >= 0.5 else '卖出'
    
    def get_trend_arrow(self, direction):
        arrows = {'up': '↗', 'down': '↘', 'neutral': '→'}
        return arrows.get(direction, '→')
    
    def format_timestamp(self, timestamp):
        """将时间戳转换为年月日时分秒格式"""
        if timestamp is None:
            return "N/A"
        try:
            dt = datetime.fromtimestamp(timestamp)
            return dt.strftime("%Y-%m-%d %H:%M:%S")
        except:
            return str(timestamp)
    
    def analyze_current_data(self, symbol, interval):
        data = self.historical_data.get(symbol, {}).get(interval)
        if not data or len(data) < 100:
            return None
        
        # 定义三种权重组合进行测试
        weight_combinations = [
            # 组合1：调高MACD权重（小周期）- 默认组合
            {
                'trend_weights': {'fisher': 0.5, 'macd': 0.25, 'kdj': 0.25},
                'reversal_weights': {'macd': 0.7, 'rsi': 0.2, 'volume': 0.1},
                'name': '高MACD权重'
            },
            # 组合2：调高RSI权重（小周期）
            {
                'trend_weights': {'fisher': 0.5, 'macd': 0.25, 'kdj': 0.25},
                'reversal_weights': {'macd': 0.3, 'rsi': 0.6, 'volume': 0.1},
                'name': '高RSI权重'
            },
            # 组合3：调高成交量权重（小周期）
            {
                'trend_weights': {'fisher': 0.5, 'macd': 0.25, 'kdj': 0.25},
                'reversal_weights': {'macd': 0.2, 'rsi': 0.2, 'volume': 0.6},
                'name': '高成交量权重'
            }
        ]
        
        print("\n=== 当前信号权重测试 ===")
        
        # 测试每种权重组合
        for i, combination in enumerate(weight_combinations):
            signals = self.calculate_signals_with_weights(data, 
                                                         combination['trend_weights'], 
                                                         combination['reversal_weights'])
            if signals and signals['prediction']:
                prediction = signals['prediction']
                print(f"权重组合 {i+1} ({combination['name']}): {prediction['direction']} (置信度: {prediction['confidence']:.3f}, RSI: {signals['indicators']['rsi']:.2f})")
                
                # 保存第一个组合（默认）的信号
                if i == 0:
                    default_signals = signals
        
        print("========================\n")
        
        if not default_signals or not default_signals['prediction']:
            return None
        
        # 使用格式化字符串打印字典内容
        print(f"当前信号检测为: {default_signals['prediction']}")
        
        # 添加市场状态分析
        market_state = self.market_state_analyzer.analyze_market_state(data)
        default_signals['market_state'] = market_state
        
        # 将市场状态信息添加到返回结果中
        # 这些信息将在start_analysis方法中被包含在card_text中
        
        self.current_signals[symbol][interval] = default_signals
        return default_signals
    
    async def start_analysis(self, interval, optimize_weights=True):
        await self.fetch_data_for_all_symbols(interval)
        
        results = []
        for symbol in self.symbols:
            signals = self.analyze_current_data(symbol, interval)
            if not signals:
                continue
            
            # 如果启用权重优化，则进行权重优化回测
            if optimize_weights:
                optimal_weights = await self.backtester.optimize_weights(symbol, interval)
                # 使用最优权重重新计算信号
                if optimal_weights:
                    data = self.historical_data.get(symbol, {}).get(interval)
                    if data:
                        new_signals = self.calculate_signals_with_weights(data, 
                                                                        optimal_weights['trend_weights'], 
                                                                        optimal_weights['reversal_weights'])
                        # 保留原有的市场状态信息
                        if new_signals and 'market_state' in signals:
                            new_signals['market_state'] = signals['market_state']
                        signals = new_signals
            
            # 使用默认权重或最优权重进行回测
            backtest_result = await self.backtester.backtest_strategy(symbol, interval)
            win_rate = backtest_result['winRate'] if backtest_result else 0
            total_tests = backtest_result['totalTests'] if backtest_result else 0
            
            prediction = signals['prediction']
            rsi = signals['indicators']['rsi']
            current_price = signals['indicators']['ma5']  # 使用MA5近似当前价格
            
            # 构建卡片文本
            current_time = self.format_timestamp(int(datetime.now().timestamp()))
            trend_direction = prediction['direction']
            trend_text = '看涨' if trend_direction == 'up' else '看跌' if trend_direction == 'down' else '横盘'
            
            card_text = [
                f"{symbol} 行情分析",
                f"{interval} | {current_time}",
                "趋势判断",
                f"{self.get_trend_arrow(trend_direction)} {trend_text} ({int(prediction['confidence'] * 100)}%)",
                "回测胜率",
                f"{win_rate}%",
                f"赢{backtest_result.get('correctPredictions', 0) if backtest_result else 0}次/共{total_tests}次"
            ]
            

            
            # 如果有最优权重，添加权重信息
            if self.backtester.optimal_weights:
                card_text.extend([
                    "\n=== 最优权重配置 ===",
                    f"配置: {self.backtester.optimal_weights['name']}",
                    f"趋势权重: F:{self.backtester.optimal_weights['trend_weights']['fisher']} M:{self.backtester.optimal_weights['trend_weights']['macd']} K:{self.backtester.optimal_weights['trend_weights']['kdj']}",
                    f"反转权重: M:{self.backtester.optimal_weights['reversal_weights']['macd']} R:{self.backtester.optimal_weights['reversal_weights']['rsi']} V:{self.backtester.optimal_weights['reversal_weights']['volume']}",
                    f"优化胜率: {self.backtester.optimal_weights['win_rate']}%"
                ])
                
                # 添加10个时间点、开仓价格和平仓价格信息
                if backtest_result and 'signals' in backtest_result and backtest_result['signals']:
                    card_text.extend(["\n=== 最优回测交易记录 ==="])
                    signals_list = backtest_result['signals'][:10]  # 取前10个信号
                    for i, signal in enumerate(signals_list):
                        signal_time = signal['time']
                        # 获取对应时间点的开仓价格和平仓价格
                        # 需要从历史数据中查找对应时间点的价格信息
                        historical_data = self.historical_data.get(symbol, {}).get('1m', [])
                        open_price = None
                        close_price = None
                        
                        for j, candle in enumerate(historical_data):
                            if candle['time'] == signal_time:
                                open_price = candle['close']  # 开仓价格为当前收盘价
                                if j + 10 < len(historical_data):
                                    close_price = historical_data[j + 10]['close']  # 10分钟后平仓价格
                                break
                        
                        if open_price is not None and close_price is not None:
                            formatted_time = self.format_timestamp(signal_time)
                            profit_loss = close_price - open_price
                            profit_percent = (profit_loss / open_price) * 100
                            card_text.append(f"{i+1}. {formatted_time.split()[1]} 开:${open_price:.2f} → 平:${close_price:.2f} ({profit_percent:+.2f}%)")
            
            # 添加市场状态信息
            market_state = signals.get('market_state', {})
            if market_state:
                # 将英文状态转换为中文 - 更新支持新的趋势结构
                high_low_structure_map = {
                    'uptrend': '上涨趋势',
                    'downtrend': '下跌趋势',
                    'potential_uptrend': '潜在上涨',
                    'potential_downtrend': '潜在下跌',
                    'ranging': '区间震荡',
                    'neutral': '中性'
                }
                ma_alignment_map = {
                    'bullish': '多头排列',
                    'bearish': '空头排列',
                    'neutral': '中性排列'
                }
                
                high_low_structure = market_state.get('details', {}).get('high_low_structure', 'N/A')
                ma_alignment = market_state.get('details', {}).get('ma_alignment', 'N/A')
                
                card_text.extend([
                    "\n=== 市场状态 ===",
                    f"状态描述: {market_state.get('description', 'N/A')}",
                    f"ADX: {market_state.get('details', {}).get('adx', 'N/A')}",
                    f"ATR: {market_state.get('details', {}).get('atr', 'N/A')}",
                    f"波动率: {market_state.get('details', {}).get('volatility', 'N/A')}",
                    f"高低点结构: {high_low_structure_map.get(high_low_structure, high_low_structure)}",
                    f"均线排列: {ma_alignment_map.get(ma_alignment, ma_alignment)}"
                ])
            
            card_text.extend([
                "\n=== 技术指标 ===",
                f"RSI: {rsi:.2f} ({self.get_rsi_level_description(rsi)})",
                f"当前价格: ${current_price:.2f}",
                f"指标依据: {self.get_macd_description(prediction['macdTrend'])}",
                # "\n=== 操作建议 ===",
                # f"{self.get_operation_suggestion(prediction)}"
            ])
            
            results.append("\n".join(card_text))
        
        return results


class Backtester:
    def __init__(self):
        self.historical_data = {}
        self.backtest_results = {}
        self.optimal_weights = None
        self.best_win_rate = 0
    
    async def backtest_strategy(self, symbol, current_interval):
        analyzer = CryptoAnalyzer()
        # 始终使用1分钟周期数据进行回测
        await analyzer.fetch_data_for_all_symbols('1m')
        print("正在回测"+current_interval)
        # 使用1分钟数据进行回测
        historical_data = analyzer.historical_data.get(symbol, {}).get('1m')
        if not historical_data or len(historical_data) < 100:
            return None
        
        current_signals = analyzer.calculate_signals(historical_data)
        if not current_signals or not current_signals['prediction']:
            return None
        
        return self.run_backtest(historical_data, current_signals, analyzer)
    
    def run_backtest(self, data, current_signals, analyzer, test_periods=200):
        max_periods = min(test_periods, len(data) - 100)
        signals = []
        correct_predictions = 0
        total_predictions = 0
        
    
  
        for i in range(100, len(data) - 10):
            if total_predictions >= max_periods:
                break
                
            test_data = data[:i+1]
            test_signals = analyzer.calculate_signals(test_data)
            print(test_signals['prediction'])
            # 修复回测逻辑：直接使用历史信号进行预测验证，不与当前信号比较
            if test_signals and test_signals['prediction']:
                total_predictions += 1
                # 计算实际价格变动：使用当前K线收盘价与10根K线后的收盘价比较
                current_price = data[i]['close']
                future_price = data[i + 10]['close']
                # 修复实际收益计算逻辑：future_price > current_price表示价格上涨，即up趋势
                actual_movement = 'up' if future_price > current_price else 'down'
                
                if test_signals['prediction']['direction'] == actual_movement:
                    correct_predictions += 1
                
                signals.append({
                    'time': data[i]['time'],
                    'prediction': test_signals['prediction']['direction'],
                    'actual': actual_movement,
                    'correct': test_signals['prediction']['direction'] == actual_movement
                })
        
        win_rate = round((correct_predictions / total_predictions) * 100) if total_predictions > 0 else 0
        
        return {
            'winRate': win_rate,
            'totalTests': total_predictions,
            'correctPredictions': correct_predictions,
            'signals': signals
        }
    
    def is_similar_signal(self, signal1, signal2):
        # 简化信号相似性检查 - 收紧条件以提高回测准确性
        return (signal1['direction'] == signal2['direction'] and
                abs(signal1['confidence'] - signal2['confidence']) <= 0.2 and
                abs(signal1['rsi'] - signal2['rsi']) <= 10)
    
    async def optimize_weights(self, symbol, interval):
        """优化权重组合，进行三次回测，每次调高一个指标权重"""
        print(f"开始权重优化回测 for {symbol} {interval}")
        
        # 定义五种更合理的权重组合
        weight_combinations = [
            # 组合1：均衡权重
            {
                'trend_weights': {'fisher': 0.4, 'macd': 0.35, 'kdj': 0.25},
                'reversal_weights': {'macd': 0.5, 'rsi': 0.3, 'volume': 0.2},
                'name': '均衡权重'
            },
            # 组合2：重视趋势指标
            {
                'trend_weights': {'fisher': 0.5, 'macd': 0.3, 'kdj': 0.2},
                'reversal_weights': {'macd': 0.4, 'rsi': 0.4, 'volume': 0.2},
                'name': '重视趋势'
            },
            # 组合3：重视反转指标
            {
                'trend_weights': {'fisher': 0.3, 'macd': 0.4, 'kdj': 0.3},
                'reversal_weights': {'macd': 0.6, 'rsi': 0.25, 'volume': 0.15},
                'name': '重视反转'
            },
            # 组合4：重视技术指标
            {
                'trend_weights': {'fisher': 0.35, 'macd': 0.4, 'kdj': 0.25},
                'reversal_weights': {'macd': 0.45, 'rsi': 0.35, 'volume': 0.2},
                'name': '重视技术指标'
            },
            # 组合5：重视成交量
            {
                'trend_weights': {'fisher': 0.45, 'macd': 0.3, 'kdj': 0.25},
                'reversal_weights': {'macd': 0.3, 'rsi': 0.3, 'volume': 0.4},
                'name': '重视成交量'
            }
        ]
        
        best_result = None
        best_win_rate = 0
        best_combination = None
        
        # 对每种权重组合进行回测
        for i, combination in enumerate(weight_combinations):
            print(f"\n测试权重组合 {i+1}: {combination['name']}")
            print(f"趋势权重: {combination['trend_weights']}")
            print(f"反转权重: {combination['reversal_weights']}")
            
            # 使用指定权重进行回测
            result = await self.backtest_strategy_with_weights(symbol, interval, 
                                                            combination['trend_weights'], 
                                                            combination['reversal_weights'])
            
            if result and result['winRate'] > best_win_rate:
                best_win_rate = result['winRate']
                best_result = result
                best_combination = combination
            
            print(f"权重组合 {i+1} 胜率: {result['winRate'] if result else 0}%")
        
        # 保存最优权重
        if best_combination:
            self.optimal_weights = {
                'trend_weights': best_combination['trend_weights'],
                'reversal_weights': best_combination['reversal_weights'],
                'name': best_combination['name'],
                'win_rate': best_win_rate
            }
            self.best_win_rate = best_win_rate
            
            print(f"\n最优权重组合: {best_combination['name']}")
            print(f"最优趋势权重: {best_combination['trend_weights']}")
            print(f"最优反转权重: {best_combination['reversal_weights']}")
            print(f"最优胜率: {best_win_rate}%")
        
        return self.optimal_weights
    
    async def backtest_strategy_with_weights(self, symbol, current_interval, trend_weights, reversal_weights):
        """使用指定权重进行回测"""
        analyzer = CryptoAnalyzer()
        # 始终使用1分钟周期数据进行回测
        await analyzer.fetch_data_for_all_symbols('1m')
        print(f"正在使用指定权重回测 {current_interval}")
        
        # 使用1分钟数据进行回测
        historical_data = analyzer.historical_data.get(symbol, {}).get('1m')
        if not historical_data or len(historical_data) < 100:
            return None
        
        # 使用指定权重计算当前信号
        current_signals = analyzer.calculate_signals_with_weights(historical_data, trend_weights, reversal_weights)
        if not current_signals or not current_signals['prediction']:
            return None
        
        return self.run_backtest_with_weights(historical_data, current_signals, analyzer, trend_weights, reversal_weights)
    
    def run_backtest_with_weights(self, data, current_signals, analyzer, trend_weights, reversal_weights, test_periods=200):
        """使用指定权重运行回测"""
        max_periods = min(test_periods, len(data) - 100)
        signals = []
        correct_predictions = 0
        total_predictions = 0
        
        for i in range(100, len(data) - 10):
            if total_predictions >= max_periods:
                break
                
            test_data = data[:i+1]
            # 使用指定权重计算测试信号
            test_signals = analyzer.calculate_signals_with_weights(test_data, trend_weights, reversal_weights)
            
            # 修复回测逻辑：直接使用历史信号进行预测验证，不与当前信号比较
            if test_signals and test_signals['prediction']:
                total_predictions += 1
                
                # 计算实际价格变动：使用当前K线收盘价与10根K线后的收盘价比较
                current_price = data[i]['close']
                future_price = data[i + 10]['close']
                # 修复实际收益计算逻辑：future_price > current_price表示价格上涨，即up趋势
                actual_movement = 'up' if future_price > current_price else 'down'
                
                if test_signals['prediction']['direction'] == actual_movement:
                    correct_predictions += 1
                
                signals.append({
                    'time': data[i]['time'],
                    'prediction': test_signals['prediction']['direction'],
                    'actual': actual_movement,
                    'correct': test_signals['prediction']['direction'] == actual_movement
                })
        
        win_rate = round((correct_predictions / total_predictions) * 100) if total_predictions > 0 else 0
        
        return {
            'winRate': win_rate,
            'totalTests': total_predictions,
            'correctPredictions': correct_predictions,
            'signals': signals
        }


